unit gameobjects;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils,Graphics;
 type Dir =(up, down, lefty, right,empty);

   const koef=0;
type
  Tentity = class (TObject)
    xcurrent:Integer;
    ycurrent:integer;
    vecx:Integer;
    vecy:Integer;
    vulnerable :Boolean;
    lastdirection:Dir;
    disfield :array [0..20, 0..12]of Boolean;

    constructor Create(cx,cy,vx,vy:Integer; vul:Boolean);
    function Canmoveto(d:Dir):Boolean;
    end;
  type
    Tghost =class (Tentity)
     Move1:Dir;
     Move2:Dir;
     Move3:Dir;
     Move4:Dir;
     procedure Move;
     procedure movechange;

    end;
  type
    Tpac = Class (Tentity)
    lives:Integer ;
    lastchosen:Dir ;
    coef:integer;
      procedure Move;
      function Findmove:Dir;
      function getmovevalue(movet:Dir):integer;
      function calcmonstdis(monst:Tghost):integer;

    end;

   var
     gamefield :array [0..20, 0..12, 0..2]of Boolean;
      Purplem, greenm, redm, pinkm: Tghost;
    Pacy:Tpac;
implementation
 constructor tentity.create(cx,cy,vx,vy:Integer; vul:Boolean);
    begin
      xcurrent:=cx;
      ycurrent:=cy;
      vecx:=vx;
      vecy:=vy;
      vulnerable:=vul;
    end;
   function Tentity.Canmoveto(d:Dir):Boolean;
 begin
     case d of
      up:begin
         if lastdirection=down then Result:=false
         else if gamefield[xcurrent,ycurrent+1,0]=True  then Result:=False
          else if ycurrent+1>12 then Result:=false
          else Result:=True;
          end;
      down: begin
                 if lastdirection=up then Result:=False
          else if gamefield[xcurrent,ycurrent-1,0]=true then Result:=false
          else if ycurrent-1<0 then Result:=false
          else Result:=True;
          end;
      lefty:
        begin
         if lastdirection=right then Result:=False
          else if gamefield[xcurrent-1,ycurrent,0]=true then Result:=false
          else if xcurrent-1<0 then Result:=false
          else Result:=True;
          end;
      right:
        begin
         if lastdirection=lefty then Result:=False
          else if gamefield[xcurrent+1,ycurrent,0]=true then Result:=false
          else if xcurrent+1>20 then Result:=false
          else Result:=True;
          end;
        empty: result:=false;
        end;

     end;
    procedure TGhost.movechange;
 begin
   Move1:=move2;
   Move2:=Move3;
  Move3:=Move4;
  Move4:=empty;
 end;
 procedure Tghost.Move;
 var canmove1:Boolean;
 begin
  canmove1:=false;
  case Move1 of
    up:begin
     if Canmoveto(up)then
     begin
       vecx:=0;
       vecy:=1;
     movechange;
       lastdirection:=up;
       canmove1:=true;
     end;
    end;
   down:begin
     if Canmoveto(down)then
     begin
       vecx:=0;
       vecy:=-1;
     movechange;
         lastdirection:=down;
         canmove1:=true;
     end;
    end;
   lefty:begin
     if Canmoveto(lefty)then
     begin
       vecx:=-1;
       vecy:=0;
      movechange;
       lastdirection:=lefty;
       canmove1:=true;
     end ;
    end;
   right:begin
     if Canmoveto(right)then
     begin
       vecx:=1;
       vecy:=0;
      movechange;
       lastdirection:=right;
       canmove1:=true;
     end ;
    end;
   empty:begin
     vecx:=0;
     vecy:=0;
     movechange;
   end;
  end;
  if canmove1=false then
  begin
    if Canmoveto(lastdirection)then
    case lastdirection of
     up: begin
        vecx:=0;
       vecy:=1;
       end;
     down:begin
       vecx:=0;
       vecy:=-1;
       end;
     lefty:begin
       vecx:=-1;
       vecy:=0;
       end;
     right:begin
       vecx:=1;
       vecy:=0;
       end;
     empty: begin
       vecx:=0;
       vecy:=0;
     end;
    end;
  end;
  xcurrent:=xcurrent+vecx;
  ycurrent:=ycurrent+vecy;
  vecx:=0;
  vecy:=0;
  if xcurrent>20 then xcurrent:=20;
  if xcurrent<0 then xcurrent:=0;
  if ycurrent<0 then ycurrent:=0;
  if ycurrent>12 then ycurrent:=12;
 end;
 procedure  Tpac.Move;
 var move1,move2,movefinal:Dir;

    move1value,move2value,r:integer;
begin
   lastchosen:=empty;
  move1:=Findmove;
  move2:=Findmove;
     if move2=empty then
     movefinal :=move1 else   begin
     move1value:=getmovevalue(move1);
     move2value:=getmovevalue(move2);
if (move1value>move2value) then movefinal:=move1 ;
if (move2value>move1value) then movefinal:=move2 ;
if move1value=move2value then begin
 begin
     Randomize;
     r:=Random(2);
     case r of
        0:movefinal:=move1;
        1:movefinal:=move2;
     end;

     end ;
  end ;

     end;

     case movefinal of
        up:begin
            vecx:=0;
            vecy:=1;
            lastdirection:=up;
           end;
        down:begin
            vecx:=0;
            vecy:=-1;
             lastdirection:=down;
           end;
        lefty:begin
            vecx:=-1;
            vecy:=0;
             lastdirection:=lefty;
           end;
        right: begin
            vecx:=1;
            vecy:=0;
             lastdirection:=right;
           end;
        empty:begin

        end;
        end;
   move1:=empty;
   move2:=empty;
   move1value:=0;
   move2value:=0;
   lastchosen:=empty;
  xcurrent:=xcurrent+vecx;
  ycurrent:=ycurrent+vecy;
  vecx:=0;
  vecy:=0;

  if xcurrent>20 then xcurrent:=20;
  if xcurrent<0 then  xcurrent:=0;
  if ycurrent<0 then ycurrent:=0;
  if ycurrent>12 then ycurrent:=12;

   end;
 function tpac.getmovevalue(movet:Dir):integer;
 var x1,y1,movevaltemp:integer;
 begin
   movevaltemp:=0;
   if movet =empty then result:=-1;
   case movet of
      Up:begin
        if gamefield[xcurrent,ycurrent+1,1]then movevaltemp:=movevaltemp+10;
        for x1:=(xcurrent-3) to (xcurrent+3) do
         for y1:=(ycurrent+1) to (ycurrent+3) do begin


        end;
        for x1:=(xcurrent-3) to (xcurrent+3) do
         for y1:=(ycurrent+1) to (ycurrent+6) do begin
           if (x1<0) or (y1<0) then movevaltemp:=movevaltemp else
           if (x1>20) or (y1>12) then movevaltemp:=movevaltemp else
         if gamefield[x1,y1,1] then movevaltemp:=movevaltemp+1;
        if (Purplem.ycurrent=y1) and (Purplem.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(Purplem));
          if (pinkm.ycurrent=y1) and (pinkm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(pinkm));
          if (greenm.ycurrent=y1)and (greenm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(greenm));
          if (redm.ycurrent=y1) and (redm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(redm));
      end;
      end;
      down:begin
        if gamefield[xcurrent,ycurrent-1,1]then movevaltemp:=movevaltemp+10;
        for x1:=(xcurrent-3) to (xcurrent+3) do
         for y1:=(ycurrent-1) to (ycurrent-3) do
        begin


        end;
        for x1:=(xcurrent-3) to (xcurrent+3) do
         for y1:=(ycurrent-6) to (ycurrent-1) do begin
            if (x1<0) or (y1<0) then movevaltemp:=movevaltemp else
           if (x1>20) or (y1>12) then movevaltemp:=movevaltemp else
         if gamefield[x1,y1,1] then movevaltemp:=movevaltemp+1;
        if (Purplem.ycurrent=y1) and (Purplem.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(Purplem));
          if (pinkm.ycurrent=y1) and (pinkm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(pinkm));
          if (greenm.ycurrent=y1)and (greenm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(greenm));
          if (redm.ycurrent=y1) and (redm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(redm));

         end;
      end;
      lefty:begin
        if gamefield[xcurrent-1,ycurrent,1]then movevaltemp:=movevaltemp+10;
        for x1:=(xcurrent-3) to (xcurrent-1) do
         for y1:=(ycurrent-3) to (ycurrent+3) do
         begin

        end;
          for x1:=(xcurrent-6) to (xcurrent-1) do
         for y1:=(ycurrent-3) to (ycurrent+3) do begin
           if (x1<0) or (y1<0) then movevaltemp:=movevaltemp else
           if (x1>20) or (y1>12) then movevaltemp:=movevaltemp else
            if gamefield[x1,y1,1] then movevaltemp:=movevaltemp+1;
        if (Purplem.ycurrent=y1) and (Purplem.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(Purplem));
          if (pinkm.ycurrent=y1) and (pinkm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(pinkm));
          if (greenm.ycurrent=y1)and (greenm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(greenm));
          if (redm.ycurrent=y1) and (redm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(redm));
      end;
      end;
      right:begin
        if gamefield[xcurrent+1,ycurrent,1]then movevaltemp:=movevaltemp+10;
        for x1:=(xcurrent+1)  to (xcurrent+3) do
         for y1:=(ycurrent-3) to (ycurrent+3)do
        begin


        end;
          for x1:=(xcurrent+1) to (xcurrent+6) do
         for y1:=(ycurrent-3) to (ycurrent+3) do begin
               if (x1<0) or (y1<0) then movevaltemp:=movevaltemp else
           if (x1>20) or (y1>12) then movevaltemp:=movevaltemp else
         if gamefield[x1,y1,1] then movevaltemp:=movevaltemp+1;
        if (Purplem.ycurrent=y1) and (Purplem.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(Purplem));
          if (pinkm.ycurrent=y1) and (pinkm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(pinkm));
          if (greenm.ycurrent=y1)and (greenm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(greenm));
          if (redm.ycurrent=y1) and (redm.xcurrent=x1) then movevaltemp:=movevaltemp+(calcmonstdis(redm));
      end;
      end;
      empty:movevaltemp:=-1000;
   end;

   Result:=movevaltemp;
 end;
  function Tpac.calcmonstdis(monst:Tghost):integer;
  var xdis,ydis,cdis:integer;
  begin
   xdis:=Pacy.xcurrent-monst.xcurrent;
   ydis:=Pacy.ycurrent-monst.ycurrent;
   cdis:=(sqr(xdis)+sqr(ydis));
   result:=-10+coef*(cdis div 10);
  end;

 function Tpac.Findmove:Dir;
 begin
   if lastchosen = empty then
   begin  {
     lastchosen:=up ;
     if Canmoveto(up)then Result:=up else begin
     repeat

       Inc(lastchosen);
     until (Canmoveto(lastchosen) ) ;
     result:=lastchosen;

     end;}
     if Canmoveto(up)then begin Result:=up ;
     lastchosen:=up;
     end
     else
     if Canmoveto(right)then begin Result:=right;lastchosen:=right; end
       else if Canmoveto(down)then begin Result:=down;lastchosen:=down; end
      else if Canmoveto(lefty)then begin Result:=lefty;lastchosen:=lefty; end
   end else
   begin {
     Inc(lastchosen);
     repeat
      if (Canmoveto(lastchosen))then begin
        Result:=lastchosen;
         lastchosen:=empty;
      end
      else if lastchosen =empty then Result:=empty else inc(lastchosen);
     until lastchosen=empty ; }
    if (Canmoveto(up)) and (lastchosen<>up)then begin Result:=up ;
     lastchosen:=up;
     end
     else
     if (Canmoveto(right))and (lastchosen<>right)then begin Result:=right;lastchosen:=right; end
       else if (Canmoveto(down))and (lastchosen<>down)then begin Result:=down;lastchosen:=down; end
      else if (Canmoveto(lefty))and (lastchosen<>lefty)then begin Result:=lefty;lastchosen:=lefty; end else Result:=empty;
   end;
 end;


end.

